GtkListItemTracker *anchor;
double anchor_align;
+ /* the last item that was selected - basically the location to extend selections from */
+ GtkListItemTracker *selected;
};
struct _ListRow
gtk_list_item_tracker_free (self->item_manager, self->anchor);
self->anchor = NULL;
}
+ if (self->selected)
+ {
+ gtk_list_item_tracker_free (self->item_manager, self->selected);
+ self->selected = NULL;
+ }
g_clear_object (&self->item_manager);
G_OBJECT_CLASS (gtk_list_view_parent_class)->dispose (object);
GtkSelectionModel *selection_model;
guint pos;
gboolean modify, extend;
+ gboolean success = FALSE;
selection_model = gtk_list_item_manager_get_model (self->item_manager);
g_variant_get (parameter, "(ubb)", &pos, &modify, &extend);
- /* XXX: handle extend by tracking the item to extend from */
+ if (extend)
+ {
+ guint start_pos = gtk_list_item_tracker_get_position (self->item_manager, self->selected);
+ if (start_pos != GTK_INVALID_LIST_POSITION)
+ {
+ guint max = MAX (start_pos, pos);
+ guint min = MIN (start_pos, pos);
+ if (modify)
+ {
+ if (gtk_selection_model_is_selected (selection_model, start_pos))
+ {
+ success = gtk_selection_model_select_range (selection_model,
+ min,
+ max - min + 1,
+ FALSE);
+ }
+ else
+ {
+ success = gtk_selection_model_unselect_range (selection_model,
+ min,
+ max - min + 1);
+ }
+ }
+ else
+ {
+ success = gtk_selection_model_select_range (selection_model,
+ min,
+ max - min + 1,
+ TRUE);
+ }
+ }
+ /* If there's no range to select or selecting ranges isn't supported
+ * by the model, fall through to normal setting.
+ */
+ }
+ if (success)
+ return;
if (modify)
{
if (gtk_selection_model_is_selected (selection_model, pos))
- gtk_selection_model_unselect_item (selection_model, pos);
+ success = gtk_selection_model_unselect_item (selection_model, pos);
else
- gtk_selection_model_select_item (selection_model, pos, FALSE);
+ success = gtk_selection_model_select_item (selection_model, pos, FALSE);
}
else
{
- gtk_selection_model_select_item (selection_model, pos, TRUE);
+ success = gtk_selection_model_select_item (selection_model, pos, TRUE);
+ }
+ if (success)
+ {
+ gtk_list_item_tracker_set_position (self->item_manager,
+ self->selected,
+ pos,
+ 0, 0);
}
}
{
self->item_manager = gtk_list_item_manager_new (GTK_WIDGET (self), ListRow, ListRowAugment, list_row_augment);
self->anchor = gtk_list_item_tracker_new (self->item_manager);
+ self->selected = gtk_list_item_tracker_new (self->item_manager);
self->adjustment[GTK_ORIENTATION_HORIZONTAL] = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
self->adjustment[GTK_ORIENTATION_VERTICAL] = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);